#!/usr/bin/python
# coding: UTF-8
#
# Autor Diego Pereira do Nascimento
# Testado e funcionando no MacOS X 10.5.5 build 9F33 em 26/09/2008:
#  Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) 
#  [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
#
# Algumas definições:
# PIM == Plataform Independent Model
# PSM == Plataform Specific Model


import re

converte_tipos = {"text":"TextField" , "date":"DateField" , "varchar":"CharField" , "int":"IntegerField" , "float":"FloatField" , \
                  "serial":"AutoField" , "boolean":"BooleanField" , "numeric":"FloatField" , "timestamp":"DateTimeField" ,        \
                  "bigint":"IntegerField" , "datetime":"DateTimeField"  , "date":"DateField" , "time" : "TimeField" ,             \
                  "bool" : "BooleanField" , "int" : "IntegerField"}

outras_classes = ["User" , "Group" , "Permission" , "Message"]


def buscaClassesExternas(tipo_atributo):
    """Se uma classe que não está no modelo for encotrada, ela será marcada como
    sendo de outro modelo"""
    if tipo_atributo.replace(" ","").lower().startswith("manytomanyfield("):
            nova_classe = tipo_atributo.replace(" ","")[16:-1]
            if outras_classes.count(nova_classe) == 0:
                    outras_classes.append(nova_classe)

    if tipo_atributo.replace(" ","").lower().startswith("foreignkey("):
            nova_classe = tipo_atributo.replace(" ","")[11:-1]
            if outras_classes.count(nova_classe) == 0:
                    outras_classes.append(nova_classe)


def imprimePSM(pre_psm, imports):
    """Ordenana a aparência do código fonte Python (PSM) e o imprime"""
    ordenado = []
    cont = 0

    for indice,valor in pre_psm.iteritems():
        valor[2] = valor[2] + "\n    def __unicode__(self):\n        return u\"\"\n"
        for nome_classe in valor[0]:
            if nome_classe not in outras_classes:
                pre_psm[nome_classe][3] += 1
        ordenado.append([indice] + valor)

    while cont < len(ordenado):
        marca = cont
        cont2 = cont + 1

        while cont2 < len(ordenado):
            if ordenado[cont][0] in ordenado[cont2][1]:
                marca = cont2
            cont2 += 1

        if marca == cont:
            cont += 1
        else:
            a = ordenado[cont]
            ordenado[cont] = ordenado[marca]
            ordenado[marca] = a

        if cont == len(ordenado) - 1:
            break

    ordenado.reverse()

    if imports:
        print imports

    for linha in ordenado:
        print linha[3]


def converteTipos(tipo_atributo, valor_atributo, nome_atributo, pre_psm, nome_classe):
    """Mapeia os tipos SQL para o Django"""
    varchar = re.compile('varchar\((\d+)\)').search(tipo_atributo)

    if tipo_atributo.replace(" ","").startswith("ManyToManyField("):
        myfor = tipo_atributo.replace(" ","")[16:-1]
        if nome_classe == myfor:
            #Em caso de um tipo recursivo, é usado "self"
            tipo_atributo = tipo_atributo.replace(myfor,"'self'")

        elif pre_psm[nome_classe][0].count(myfor) == 0:
            #Adicionando a classe relacionada
            if myfor not in outras_classes:
                #Caso seja usado classes Auth ou externas via visibilidade protegida do Dia
                pre_psm[nome_classe][0].append(myfor)

        tipo_atributo = "models." + tipo_atributo
        if len(valor_atributo) > 0:
            tipo_atributo = tipo_atributo.replace(")", "," + valor_atributo + ")")

    elif tipo_atributo.find("Field") != -1:
        if tipo_atributo.count("()") > 0 and len(valor_atributo) > 0:
            tipo_atributo = "models.%s" % tipo_atributo.replace(")", "," + valor_atributo + ")")
        else:
            tipo_atributo = "models.%s(%s)" % (tipo_atributo, valor_atributo)

    elif tipo_atributo.replace(" ","").startswith("ForeignKey("):
        myfor = tipo_atributo.replace(" ","")[11:-1]

        if nome_classe == myfor:
            #Em caso de um tipo recursivo, é usado "self"
            tipo_atributo = tipo_atributo.replace(myfor,"'self'")

        elif pre_psm[nome_classe][0].count(myfor) == 0:
            #Adicionando classes estrangeiras
            if myfor not in outras_classes:
                #Caso seja usado classes Auth
                pre_psm[nome_classe][0].append(myfor)

        tipo_atributo = "models." + tipo_atributo
        if len(valor_atributo) > 0:
            tipo_atributo = tipo_atributo.replace(")", "," + valor_atributo + ")")

    elif varchar == None:
        tipo_atributo = "models." + converte_tipos[tipo_atributo.strip().lower()] + "(" + valor_atributo + ")"
    else :
        tipo_atributo = "models.CharField(max_length=" + varchar.group(1) + ")"
        if len(valor_atributo) > 0:
            tipo_atributo = tipo_atributo.replace(")", ", " + valor_atributo + " )")

    if not (nome_atributo == "id" and tipo_atributo == "AutoField()"):
        pre_psm[nome_classe][2] = pre_psm[nome_classe][2] + ("    %s = %s\n" % (nome_atributo, tipo_atributo))